package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.constants.media.WeMediaConstants;
import com.heima.common.exception.LeadNewsException;
import com.heima.file.service.FileStorageService;
import com.heima.model.common.dto.PageResponseResult;
import com.heima.model.common.dto.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dto.WmMaterialDto;
import com.heima.model.wemedia.pojo.WmMaterial;
import com.heima.model.wemedia.pojo.WmNewsMaterial;
import com.heima.model.wemedia.pojo.WmUser;
import com.heima.utils.threadlocal.WmThreadLocalUtils;
import com.heima.wemedia.mapper.MaterialMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.MaterialService;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.common.protocol.types.Field;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @author Ronaldo
 * @date 2021/8/3
 */
@Transactional
@Service
@Slf4j
@SuppressWarnings("all")
public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, WmMaterial> implements MaterialService {

    @Autowired
    private FileStorageService fileStorageService;

    @Value("${file.oss.prefix}")
    private String prefix;

    @Value("${file.oss.web-site}")
    private String webSite;

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Override
    public ResponseResult uploadPicture(MultipartFile multipartFile) {

        //判断当前是否用户已登陆
        WmUser user = WmThreadLocalUtils.getUser();
        if (Objects.isNull(user)) {
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }

        //获取唯一文件名
        String fileName = UUID.randomUUID().toString().replace("-", "");

        //获取原文件名 得到文件后缀名
        String originalFilename = multipartFile.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String completeFileName = fileName + suffix;

        //执行文件上传
        String path = null;
        try {
            path = fileStorageService.store(prefix, completeFileName, multipartFile.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
            throw new LeadNewsException(AppHttpCodeEnum.FILE_UPLOAD_FAIL);
        }

        //保存素材信息
        WmMaterial wmMaterial = new WmMaterial();
        wmMaterial.setUserId(user.getId());
        wmMaterial.setCreatedTime(new Date());
        wmMaterial.setUrl(path);
        wmMaterial.setType(WeMediaConstants.MATERIAL_TYPE_PICTURE);
        wmMaterial.setIsCollection(WeMediaConstants.CANCEL_COLLECT_MATERIAL);
        save(wmMaterial);

        //设置url返回前端  便于展示
        wmMaterial.setUrl(webSite + wmMaterial.getUrl());

        //清理ThreadLocal
        WmThreadLocalUtils.clear();

        return ResponseResult.okResult(wmMaterial);
    }

    @Override
    public ResponseResult queryMaterialList(WmMaterialDto wmMaterialDto) {

        //分页参数合法性检查
        wmMaterialDto.checkParam();

        // 此操作需要登录
        WmUser user = WmThreadLocalUtils.getUser();
        if (Objects.isNull(user)){
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }

        //组装查询条件
        LambdaQueryWrapper<WmMaterial> materialLambdaQueryWrapper = new LambdaQueryWrapper<>();

        //是否查看收藏
        Short isCollection = wmMaterialDto.getIsCollection();
        if (Objects.nonNull(isCollection) && WeMediaConstants.COLLECT_MATERIAL.equals(isCollection)){
            materialLambdaQueryWrapper.eq(WmMaterial::getIsCollection,isCollection);
        }

        //当前用户的资源 及 按照创建时间倒排
        materialLambdaQueryWrapper.eq(WmMaterial::getUserId,user.getId());
        materialLambdaQueryWrapper.orderByDesc(WmMaterial::getCreatedTime);

        //执行分页查询
        IPage<WmMaterial> page = new Page<>(wmMaterialDto.getPage(),wmMaterialDto.getSize());
        page = this.page(page,materialLambdaQueryWrapper);

        //封装响应数据
        PageResponseResult pageResponseResult = new PageResponseResult(wmMaterialDto.getPage(), wmMaterialDto.getSize(), (int) page.getTotal());
        List<WmMaterial> materialList = page.getRecords();
        materialList.forEach(material -> {
            material.setUrl(webSite + material.getUrl());
        });
        pageResponseResult.setData(materialList);

        //清理ThreadLocal
        WmThreadLocalUtils.clear();

        return pageResponseResult;
    }

    @Override
    public ResponseResult deleteMaterialById(Integer id) {

        //判断当前是否用户登录
        WmUser user = WmThreadLocalUtils.getUser();
        if (Objects.isNull(user)){
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }

        //判断该id是否有对应资源
        WmMaterial material = getById(id);
        if (Objects.isNull(material)){
            throw new LeadNewsException(AppHttpCodeEnum.NOT_FOUND_MATERIAL);
        }

        //判断当前资源是否有文章引用
        WmNewsMaterial wmNewsMaterial = wmNewsMaterialMapper.selectOne(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getMaterialId, id));
        if (Objects.nonNull(wmNewsMaterial)){
            throw new LeadNewsException(AppHttpCodeEnum.MATERIAL_IN_USE);
        }

        //执行删除资源操作
        removeById(id);

        //删除阿里云资源
        fileStorageService.delete(material.getUrl());

        //清楚ThreadLocal
        WmThreadLocalUtils.clear();;

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

    }

    @Override
    public ResponseResult collect(Integer id, Short collectMaterial) {
        //判断当前是否用户登录
        WmUser user = WmThreadLocalUtils.getUser();
        if (Objects.isNull(user)){
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }

        //判断该id是否有对应资源
        WmMaterial material = getById(id);
        if (Objects.isNull(material)){
            throw new LeadNewsException(AppHttpCodeEnum.NOT_FOUND_MATERIAL);
        }

        //执行更新操作
        this.update(Wrappers.<WmMaterial>lambdaUpdate().eq(WmMaterial::getId,id).set(WmMaterial::getIsCollection,collectMaterial));

        //清理ThreadLocal
        WmThreadLocalUtils.clear();

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
